package com.addplus.townmall.server.web.consumer.action.ueditor;

import com.addplus.townmall.server.api.constant.ErrorCode;
import com.addplus.townmall.server.api.mapper.exam.KnowledgeMapper;
import com.addplus.townmall.server.api.mapper.exam.QuestionMapper;
import com.addplus.townmall.server.api.model.base.ReturnDataSet;
import com.addplus.townmall.server.api.model.exam.Question;
import com.addplus.townmall.server.oss.service.OssService;
import com.addplus.townmall.server.web.consumer.container.AddplusContainer;
import com.alibaba.dubbo.rpc.RpcContext;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author fuyq
 * @date 2018/8/8
 */
@RestController
@RequestMapping(value = "ueditor")
public class UeditorAction {
    @Autowired
    private AddplusContainer addplusContainer;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private KnowledgeMapper knowledgeMapper;

    @Autowired
    private OssService ossService;
    private enum ImportStringLineTypeForChoice{START,CONTENT,OPTION_A,OPTION_B,OPTION_C,OPTION_D,OPTION_E,OPTION_F,
        OPTION_G,OPTION_H,ANSWER,KNOWLEDGE,SCORE,DIFFICULTY,DESCRIPTION};//题干、选项(A~H)、答案/、biaoq，分数，解析，难度
    @RequestMapping(value = "/uploadQuestionFile", method = RequestMethod.POST)
    public ReturnDataSet uploadQuestionFile(MultipartHttpServletRequest multipartRequest) throws IOException {
        MultiValueMap<String, MultipartFile> multiValueMap = multipartRequest.getMultiFileMap();
        List<MultipartFile> multipartFiles = new ArrayList<>();

        for (Map.Entry<String, List<MultipartFile>> entry : multiValueMap.entrySet()) {
            multipartFiles.addAll(entry.getValue());
        }
        for(MultipartFile file:multipartFiles){
            String textFileName=file.getOriginalFilename();
            File uFile=null;
            try {
                if(textFileName.endsWith(".doc")){ //判断文件格式
                    InputStream fis = file.getInputStream();
                    byte[] bytes = new byte[1024];
                    while ((fis.read(bytes)) != -1) {
                        System.out.println(bytes);
                    }
                    WordExtractor wordExtractor = new WordExtractor(fis);//使用HWPF组件中WordExtractor类从Word文档中提取文本或段落
                    int i=1;
                    analysisWordTextDoc(wordExtractor.getParagraphText());
                    for(String words : wordExtractor.getParagraphText()){//获取段落内容
                        System.out.println(words);
                        i++;
                    }
                    fis.close();
                }
                if(textFileName.endsWith(".docx")){
                    uFile = new File("tempFile.docx");//创建一个临时文件

                    FileCopyUtils.copy(file.getBytes(), uFile);//复制文件内容
                    OPCPackage opcPackage = POIXMLDocument.openPackage("tempFile.docx");//包含所有POI OOXML文档类的通用功能，打开一个文件包。
                    XWPFDocument document = new XWPFDocument(opcPackage);//使用XWPF组件XWPFDocument类获取文档内容
                    List<XWPFParagraph> paras = document.getParagraphs();

                    for(XWPFParagraph paragraph : paras){
                        String line = paragraph.getText();
                        System.out.println(line);
//                        i++;
                    }
                    analysisWordTextDocx(paras);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(uFile!=null){
                    uFile.delete();
                }
            }
        }

       return null;
    }

    private void analysisWordTextDoc(String[] paras){
        int cnt = 0;
        int i=1;
        String line="";
        String content = "";//题干
        String[] choices=new String[8];//选项
        String answer = "";//答案
        String knowledge="";//知识点
        String score="";
        String description="";
        String difficulty="";
        String questionType="";
        Integer choiceNum=0;
        Boolean isEnd=false;
        ImportStringLineTypeForChoice type=null;
        for(String str : paras){
            line = str;
//                        line=line.replace(" ", "");//将UTF-8的特殊空格替换掉，编码c2a0
//                        line=line.replace((char)65279, ' ');//对有BOM头的第一行做处理
            line=line.trim();
            String qt=matchType(line);
            if(qt!=null&&questionType.equals("")){
                questionType=qt;
            }
            if(line.equals("")){
                continue;  //空行被忽略
            }else if(line.contains("[结束]")||qt!=null){
                if(content!=null&&!"".equals(content)){
                    Question question=new Question();
                    question.setContent(content);
                    question.setAnswer(answer);
                    question.setQuestionType(questionType);
                    question.setDifficulty(difficulty);
                    question.setGmtModified(new Date());
                    question.setGmtCreate(new Date());
                    question.setContributor(RpcContext.getContext().getAttachment("id"));
                    question.setIsDeleted(0);
                    if(score!=null&&!score.equals("")){
                        question.setScore(Integer.valueOf(score));
                    }
                    question.setChoiceNum(choiceNum);
                    if(choices[0]!=null&&!"".equals(choices[0])){
                        question.setChoiceA(choices[0]);
                    }
                    if(choices[1]!=null&&!"".equals(choices[1])){
                        question.setChoiceB(choices[1]);
                    }
                    if(choices[2]!=null&&!"".equals(choices[2])){
                        question.setChoiceC(choices[2]);
                    }
                    if(choices[3]!=null&&!"".equals(choices[3])){
                        question.setChoiceD(choices[3]);
                    }
                    if(choices[4]!=null&&!"".equals(choices[4])){
                        question.setChoiceE(choices[4]);
                    }
                    if(choices[5]!=null&&!"".equals(choices[5])){
                        question.setChoiceF(choices[5]);
                    }
                    if(choices[6]!=null&&!"".equals(choices[6])){
                        question.setChoiceG(choices[6]);
                    }
                    if(choices[7]!=null&&!"".equals(choices[7])){
                        question.setChoiceH(choices[7]);
                    }
                    if(knowledge!=null&&!"".equals(knowledge)){
                        question.setKnowledgeName(knowledge);
                    }
                    questionMapper.insert(question);
//                                System.out.println(question);

                    content = "";//题干
                    choices=new String[8];//选项
                    answer = "";//答案
                    knowledge="";//知识点
                    description="";
                    difficulty="";
                    score="";
                    choiceNum=0;
                    cnt++;
                    questionType=qt;
                }

                if(qt!=null){
                    content = line.substring((line.indexOf(questionType)+questionType.length()+1)).trim();
                    type=ImportStringLineTypeForChoice.CONTENT;
                }
            }else if(line.startsWith("[分数]")){
                score = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.SCORE;
            }else if(line.startsWith("[难度]")){
                difficulty = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.DESCRIPTION;
            }else if(line.startsWith("[解析]")){
                description = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.DIFFICULTY;
            }else if(line.startsWith("[分类]")){
                knowledge = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.KNOWLEDGE;
            }else if(line.startsWith("[答案]")){
                answer = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.ANSWER;
            }else if(isChoice(line)){//不能用isLetter()，因汉字也会为true
                char firstChar = line.charAt(0);
                switch(firstChar){
                    case 'A':
                        choices[0]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_A;
                        break;
                    case 'B':
                        choices[1]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_B;
                        break;
                    case 'C':
                        choices[2]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_C;
                        break;
                    case 'D':
                        choices[3]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_D;
                        break;
                    case 'E':
                        choices[4]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_E;
                        break;
                    case 'F':
                        choices[5]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_F;
                        break;
                    case 'G':
                        choices[6]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_G;
                        break;
                    case 'H':
                        choices[7]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_H;
                        break;
                }

            }else{  //不属于上述任何一种情况，则说明题干、选项、答案、知识点占用了多行的情况。
                switch(type){
                    case DESCRIPTION:
                        description+="\n"+line;
                        break;
                    case CONTENT:
                        content+="\n"+line;
                        break;
                    case ANSWER:
                        answer+="\n"+line;
                        break;
                    case KNOWLEDGE:
                        knowledge+="\n"+line;
                        break;
                    case OPTION_A:
                        choices[0]+="\n"+line;
                        break;
                    case OPTION_B:
                        choices[1]+="\n"+line;
                        break;
                    case OPTION_C:
                        choices[2]+="\n"+line;
                        break;
                    case OPTION_D:
                        choices[3]+="\n"+line;
                        break;
                    case OPTION_E:
                        choices[4]+="\n"+line;
                        break;
                    case OPTION_F:
                        choices[5]+="\n"+line;
                        break;
                    case OPTION_G:
                        choices[6]+="\n"+line;
                        break;
                    case OPTION_H:
                        choices[7]+="\n"+line;
                        break;
                    default:break;
                }
            }
        }
        System.out.println(cnt);
    }

    private void analysisWordTextDocx(List<XWPFParagraph> paras){
        int cnt = 0;
        int i=1;
        String line="";
        String content = "";//题干
        String[] choices=new String[8];//选项
        String answer = "";//答案
        String knowledge="";//知识点
        String score="";
        String description="";
        String difficulty="";
        String questionType="";
        Integer choiceNum=0;
        Boolean isQuestion=false;
        ImportStringLineTypeForChoice type=ImportStringLineTypeForChoice.START;
        for(XWPFParagraph paragraph : paras){
            line = paragraph.getText();
//                        line=line.replace(" ", "");//将UTF-8的特殊空格替换掉，编码c2a0
//                        line=line.replace((char)65279, ' ');//对有BOM头的第一行做处理
            line=line.trim();
            String qt=matchType(line);
            if(qt!=null&&questionType.equals("")){
                questionType=qt;

            }
            if(line.equals("")){
                continue;  //空行被忽略
            }else if(line.contains("[结束]")||qt!=null){
                if(content!=null&&!"".equals(content)){
                    insertQuestion(content,answer,questionType,difficulty,score,choiceNum,knowledge,choices);
                    content = "";//题干
                    choices=new String[8];//选项
                    answer = "";//答案
                    knowledge="";//知识点
                    description="";
                    difficulty="";
                    score="";
                    choiceNum=0;
                    cnt++;
                    questionType=qt;
                }

                if(qt!=null){
                    content = line.substring((line.indexOf(questionType)+questionType.length()+1)).trim();
                    type=ImportStringLineTypeForChoice.CONTENT;
                }
            }else if(line.startsWith("[分数]")){
                score = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.SCORE;
            }else if(line.startsWith("[难度]")){
                difficulty = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.DESCRIPTION;
            }else if(line.startsWith("[解析]")){
                description = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.DIFFICULTY;
            }else if(line.startsWith("[分类]")){
                knowledge = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.KNOWLEDGE;
            }else if(line.startsWith("[答案]")){
                answer = line.substring(4).trim();
                type=ImportStringLineTypeForChoice.ANSWER;
            }else if(isChoice(line)){//不能用isLetter()，因汉字也会为true
                char firstChar = line.charAt(0);
                switch(firstChar){
                    case 'A':
                        choices[0]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_A;
                        break;
                    case 'B':
                        choices[1]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_B;
                        break;
                    case 'C':
                        choices[2]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_C;
                        break;
                    case 'D':
                        choices[3]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_D;
                        break;
                    case 'E':
                        choices[4]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_E;
                        break;
                    case 'F':
                        choices[5]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_F;
                        break;
                    case 'G':
                        choices[6]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_G;
                        break;
                    case 'H':
                        choices[7]=firstStringLineProcess(line);choiceNum++;
                        type=ImportStringLineTypeForChoice.OPTION_H;
                        break;
                }

            }else{  //不属于上述任何一种情况，则说明题干、选项、答案、知识点占用了多行的情况。
                switch(type){
                    case DESCRIPTION:
                        description+="\n"+line;
                        break;
                    case CONTENT:
                        content+="\n"+line;
                        break;
                    case ANSWER:
                        answer+="\n"+line;
                        break;
                    case KNOWLEDGE:
                        knowledge+="\n"+line;
                        break;
                    case OPTION_A:
                        choices[0]+="\n"+line;
                        break;
                    case OPTION_B:
                        choices[1]+="\n"+line;
                        break;
                    case OPTION_C:
                        choices[2]+="\n"+line;
                        break;
                    case OPTION_D:
                        choices[3]+="\n"+line;
                        break;
                    case OPTION_E:
                        choices[4]+="\n"+line;
                        break;
                    case OPTION_F:
                        choices[5]+="\n"+line;
                        break;
                    case OPTION_G:
                        choices[6]+="\n"+line;
                        break;
                    case OPTION_H:
                        choices[7]+="\n"+line;
                        break;
                }
            }
        }
        System.out.println(cnt);
    }

    private void insertQuestion(String content,String answer,String questionType,String difficulty,String score,Integer choiceNum,String knowledge,String[] choices){
        Question question=new Question();
        question.setContent(content);
        question.setAnswer(answer);
        question.setQuestionType(questionType);
        question.setDifficulty(difficulty);
        question.setGmtModified(new Date());
        question.setGmtCreate(new Date());
        question.setContributor(RpcContext.getContext().getAttachment("id"));
        question.setIsDeleted(0);
        if(knowledge!=null&&!"".equals(knowledge)){
            question.setKnowledgeName(knowledge);
        }
        if(score!=null&&!score.equals("")){
            question.setScore(Integer.valueOf(score));
        }
        question.setChoiceNum(choiceNum);
        if(choices[0]!=null&&!"".equals(choices[0])){
            question.setChoiceA(choices[0]);
        }
        if(choices[1]!=null&&!"".equals(choices[1])){
            question.setChoiceB(choices[1]);
        }
        if(choices[2]!=null&&!"".equals(choices[2])){
            question.setChoiceC(choices[2]);
        }
        if(choices[3]!=null&&!"".equals(choices[3])){
            question.setChoiceD(choices[3]);
        }
        if(choices[4]!=null&&!"".equals(choices[4])){
            question.setChoiceE(choices[4]);
        }
        if(choices[5]!=null&&!"".equals(choices[5])){
            question.setChoiceF(choices[5]);
        }
        if(choices[6]!=null&&!"".equals(choices[6])){
            question.setChoiceG(choices[6]);
        }
        if(choices[7]!=null&&!"".equals(choices[7])){
            question.setChoiceH(choices[7]);
        }
        questionMapper.insert(question);
    }
    /**
     * 选择题型
     * @param line
     * @return
     */
    private static String matchType(String line){
        if(line.contains("[单选题]")){
            return "单选题";
        }
        if(line.contains("[多选题]")){
            return "多选题";
        }
        if(line.contains("[判断题]")){
            return "判断题";
        }
        if(line.contains("[填空题]")){
            return "填空题";
        }
        if(line.contains("[解答题]")){
            return "解答题";
        }
        if(line.contains("[编程题]")){
            return "编程题";
        }
        return null;
    }

    /*
     * 对题干、选项等的第一行，先去掉第一个字符（字母或数字后），如果还有逗号或句号等分隔符，也去掉。
     */
    private static String firstStringLineProcess(String line){
        String result = line.substring(1);
        char firstNoLetterChar=result.charAt(0);
        if(firstNoLetterChar=='.' || firstNoLetterChar=='．' || firstNoLetterChar=='。' ||
                firstNoLetterChar==',' || firstNoLetterChar=='，' ){
            result = result.substring(1).trim();
        }
        return result;
    }

    /*
     * 对题干、选项等的第一行，先去掉第一个字符（字母或数字后），如果还有逗号或句号等分隔符，也去掉。
     */
    private static Boolean isChoice(String line){
        if(line.length()<2){
            return false;
        }
        char first=line.charAt(0);
        if(first!='A'&&first!='B'&&first!='C'&&first!='D'&&first!='E'&&first!='F'&&first!='G'&&first!='H'){
            return false;
        }
        char second=line.charAt(2);
//        if(second!='.' && second!='．' && second!='。' && second!=',' && second!='，' ){
//            return false;
//        }
        return true;
    }



















    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public ReturnDataSet uploadFile(MultipartHttpServletRequest multipartRequest) {
        MultiValueMap<String, MultipartFile> multiValueMap = multipartRequest.getMultiFileMap();
        List<MultipartFile> multipartFiles = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> entry : multiValueMap.entrySet()) {
            multipartFiles.addAll(entry.getValue());
        }
        List<String> fieList = ossService.upload(multipartFiles, null, null, true);
        ReturnDataSet returnDataSet;
        if (fieList.size() > 0) {
            returnDataSet = new ReturnDataSet(ErrorCode.SYS_SUCCESS, fieList.get(0));
        } else {
            returnDataSet = new ReturnDataSet(ErrorCode.SYS_ERROR_NULLDATE, "");
        }
        return returnDataSet;
    }

    @RequestMapping(value = "/uploadImage", method = RequestMethod.POST)
    public ReturnDataSet uploadImageFile(Integer width, Integer height, MultipartHttpServletRequest multipartRequest) {
        MultiValueMap<String, MultipartFile> multiValueMap = multipartRequest.getMultiFileMap();
        List<MultipartFile> multipartFiles = new ArrayList<>();
        for (Map.Entry<String, List<MultipartFile>> entry : multiValueMap.entrySet()) {
            multipartFiles.addAll(entry.getValue());
        }
        List<String> imageList = ossService.upload(multipartFiles, width, height, true);
        ReturnDataSet returnDataSet;
        if (imageList.size() > 0) {
            returnDataSet = new ReturnDataSet(ErrorCode.SYS_SUCCESS, imageList.get(0));
        } else {
            returnDataSet = new ReturnDataSet(ErrorCode.SYS_ERROR_NULLDATE, "");
        }
        return returnDataSet;
    }
}
